require( "gip")
require( "util")
require( "imageswf")

local basePath
local genPath

local failedCount
local successCount
local descFailedCount

local srcImageSuffix = ".tga"
local defaultPlayV = 8

local defaultBaseX = -1
local defaultBaseY = -1

local effectImages = {}
local effectImagesKeys = {}

local function saveImageToTable( image, baseX, baseY, name)
    local x, y, w, h = image.validArea()
    io.write( ".")
    local newImage = image.cut( x, y, w, h)
    if newImage == nil then
        return false
    end
    
    local v = {}
    v.image = newImage
    v.offsetX = x - baseX 
    v.offsetY = y - baseY 
    v.w = w
    v.h = h
    
    effectImages[name] = v
    table.insert(effectImagesKeys, name)
    return true
end

local function serialFileCallBack( filename, isFile)
    filename = string.lower(filename)
    local dotPos = string.find( filename, srcImageSuffix, #filename - 4)
    if dotPos == nil then
        dotPos = string.find( filename, ".png", #filename - 4)
    end
    if dotPos == nil then
        return
    end
    
    local image = gip.load( filename);
    if image == nil then
        print( "\n")
        print( filename .. "load failed!")
        failedCount = failedCount + 1
        return
    end

    local name = noSuffixFileName( filename)
    local oldW = image.getW()
    local oldH = image.getH()
    local baseX = defaultBaseX
    if baseX < 0 then
        baseX = math.floor( oldW / 2)
    end
    local baseY = defaultBaseY
    if defaultBaseY < 0 then
        baseY = math.floor( oldH / 2)
    end

    io.write("-")
    if saveImageToTable( image, baseX, baseY, name) == true then
        successCount = successCount + 1
    end
    image = nil
end

local function getSplitImageDesc( filename)
    local dirName = getParentDirName( filename)
    local pos0 = string.find( dirName, "-")
    if pos0 == nil then
        return nil
    end
    local pos1 = string.find( dirName, "-", pos0 + 1)
    if pos1 == nil then
        return nil
    end
    local total = tonumber(string.sub(dirName, pos0 + 1, pos1 - 1))
    if total == nil then
        return nil
    end

    local row
    local col
    local v
    local pos2 = string.find( dirName, "-", pos1 + 1)
    if pos2 == nil then
        col = tonumber(string.sub(dirName, pos1 + 1))
        if col == nil then
            return nil
        end
        v = defaultPlayV 
    else
        col = tonumber(string.sub(dirName, pos1 + 1, pos2 - 1))
        if col == nil then
            return nil
        end
        v = tonumber(string.sub(dirName, pos2+1))
        if v == nil then
            v = defaultPlayV 
        end
    end
    row = math.floor(total / col)
    return total, row, col, v
end

local function splitFileCallBack( filename, isFile)
    filename = string.lower(filename)
    local dotPos = string.find( filename, srcImageSuffix, #filename - 4)
    if dotPos == nil then
        dotPos = string.find( filename, ".png", #filename - 4)
    end
    if dotPos == nil then
        return
    end

    local image = gip.load( filename);
    if image == nil then
        print( "\n")
        print( filename .. "load failed!")
        failedCount = failedCount + 1
        return
    end

    local oldW = image.getW()
    local oldH = image.getH()
    local total, row, col, v = getSplitImageDesc( filename)
    if total == nil then
        print( "\n" .. filename .. " parse desc failed!")
        failedCount = failedCount + 1
        return
    end
    io.write("-")

    local r, c
    local x = 0
    local y = 0
    local w = math.floor( oldW / col)
    local h = math.floor( oldH / row)
    local count = 1 
    for r = 1, row do
        for c = 1, col do
            local newImage = image.cut( x, y, w, h)
            local name = numbertofixstr( count, 3)
            if saveImageToTable( newImage, math.floor(w/2),
                math.floor(h/2), name) == false then
                print( "save " .. filename .. " " .. row .. " " .. col .. "failed")
                return
            end
            x = x + w
            count = count + 1
            if count > total then
                break
            end
        end
        if count > total then
            break
        end
        x = 0
        y = y + h
    end
    successCount = successCount + 1
end

local function outputJai( effectImages, effectImagesKeys, newPath)
    newPath = newPath .. ".jai"

    local jaiFile, errMsg = io.open( newPath, "wb")
    if jaiFile == nil then
        print( "open " .. newPath .. " failed: " .. errMsg)
        failedCount = failedCount + 1
        return
    end

    local headerSize = 0

    jaiFile:write( "jai")
    jaiFile:write( numbertobytes(0, 1))
    headerSize = headerSize + 4 

    jaiFile:write( numbertobytes(1, 2))
    headerSize = headerSize + 2 

    local imageCount = table.getn( effectImagesKeys) 
    jaiFile:write( numbertobytes(imageCount, 2))
    headerSize = headerSize + 2 
    
    local ok = true
    for _, k in ipairs(effectImagesKeys) do
        local v = effectImages[k]
        headerSize = headerSize + #k
        -- k_len, w, h, ox, oy, offset[4], flag
        headerSize = headerSize + 2 * 6 + 4
        if addMode then
            v.buf = v.image.saveToMemory( "jpg")
            v.flag = 1 
        else
            v.buf = v.image.saveToMemory( "jai")
            v.flag = 2 
        end
        if v.buf == nil then
            ok = false
            failedCount = failedCount + 1
            print( filename .. "/" .. k .. " failed") 
            return;
        end
    end
   
    local offset = headerSize
    for _, k in ipairs(effectImagesKeys) do
        local v = effectImages[k]
        v.offset = offset
        offset = offset + string.len( v.buf)
        if addMode then
            offset = offset + 4     -- for jpeg len
        end
    end

    for _, k in ipairs(effectImagesKeys) do
        local v = effectImages[k]
        jaiFile:write( numbertobytes(#k, 2))
        jaiFile:write( k)
        jaiFile:write( numbertobytes(v.w, 2))
        jaiFile:write( numbertobytes(v.h, 2))
        jaiFile:write( numbertobytes(v.offsetX, 2))
        jaiFile:write( numbertobytes(v.offsetY,2))
        jaiFile:write( numbertobytes(v.offset, 4))
        jaiFile:write( numbertobytes(v.flag, 2))
    end

    for _, k in ipairs(effectImagesKeys) do
        local v = effectImages[k]
        if addMode then
            jaiFile:write( numbertobytes(string.len(v.buf), 4))
        end
        jaiFile:write( v.buf)
    end

    jaiFile:flush()
    jaiFile:close()
end

local function outputSwf( effectImages, effectImagesKeys, efctName, newPath, addMode)
    newPath = newPath .. ".swf"
    gip.createParentDir( newPath)

    local i, j = string.find( efctName, "-")
    local className = string.sub( efctName, 1, i - 1)

    local srcFile = genSwf( effectImages, effectImagesKeys, className, 75, addMode)
    print( srcFile)
    os.execute( "cp " .. srcFile .. " " .. newPath) 
end

local function effectCallback( filename, isFile)
    if ifFile then
        return
    end
    effectImages = {}
    effectImagesKeys = {}
    
    local d1Name, d2Name = splitPath( filename)
    local addMode = false
    if string.find( d2Name, "a") == 1 then
        addMode = true
    end

    local minusCount = find_num( d2Name, "-")
    if minusCount > 1 then
        gip.transDir( filename, splitFileCallBack, false)
    else
        gip.transDir( filename, serialFileCallBack, false)
    end

    table.sort( effectImagesKeys)
    local imageCount = table.getn( effectImagesKeys) 
    if imageCount < 1 then
        return
    end

    -- 整理保存的名字
    local newD2Name
    if minusCount == 0 then
        newD2Name = d2Name .. "-" .. tostring(defaultPlayV)
    elseif minusCount == 2 then
        local i, j = string.find( d2Name, "-")
        newD2Name = string.sub( d2Name, 1, i - 1) .. "-" .. tostring( defaultPlayV)
    elseif minusCount > 2 then
        local i, j = find_last(d2Name, "-")
        newD2Name = string.sub( d2Name, 1, i) .. string.sub( d2Name, i + 1)
    else
        newD2Name = d2Name
    end
    local relPath = string.sub( d1Name, #basePath + 1)
    local newPath = genPath .. relPath
    local newPath = newPath .. newD2Name
    
    gip.createParentDir( newPath)

    --outputJai( effectImages, effectImagesKeys, newPath)
    outputSwf( effectImages, effectImagesKeys, newD2Name, newPath, addMode)

end

local function genEffect( srcPath, dstPath)
    basePath = srcPath
    genPath = dstPath
    
    failedCount = 0
    successCount = 0
    descFailedCount = 0
    
    gip.setJpgQuality( 75)
    gip.transDir( basePath, effectCallback, false)
    
    if failedCount == 0 and descFailedCount == 0 then
        print( "It's all OK!")
    else
        local s = string.format( "success: %d, failed: %d, desc fialed: %d",
            successCount, failedCount, descFailedCount)
        print( s)
    end

end

return function( target) 
    gip.init()
    if target == "trap" then
        defaultBaseX = 256 
        defaultBaseY = 282
        genEffect( "/export/arts/pak/trap_png", "/export/arts/pak/trap_pak")
    else
        defaultBaseX = -1
        defaultBaseY = -1
        genEffect( "/export/arts/pak/effect_tga", "/export/arts/pak/effect_pak")
    end
    gip.deInit()
end

